<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
// ------------------------------------------------------------------------

/**
 * CodeIgniter Benchmark Class
 */
class CI_Benchmark {

    /**
     * List of all benchmark markers and when they were added
     */
    var $marker = array();

    // --------------------------------------------------------------------

    /**
     * Set a benchmark marker
     */
    function mark($name)
    {
        //这个方法其实很简单，就是在程序的任意地方调用地方法时，会记录当前的时间点。
        $this->marker[$name] = microtime();
    }

    // --------------------------------------------------------------------

    /**
     * Calculates the time difference between two marked points.
     * 计算出两个时间点之间的时间。
     */
    function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
    {
        /*
         * 如果没有给出明确的时间点，那么会计算出整个程序运行的时间。
         * 怎么可以做到计算出整个程序的运行时间的呢？其实执行此计算的是Output组件。
         * 而调用Benchmark::elapsed_time();（无参数）的时候，实质上先返回的并不是
         * 整个程序运行的时间，也不可能做到，实质返回的是一个{elapsed_time}标签，然后
         * Output在处理输出的时候，再计算出整个程序运行时间，因为处理输出阶段程序可以视
         * 为处于最后阶段，于是可以近似计算出总时间，然后把输出中的{elapsed_time}替换掉。
         * 下面的memory_usage()原理相同。
         * 详见：core/Output.php 中的_display()方法。
         */
        if ($point1 == '')
        {
            return '{elapsed_time}';
        }

        if ( ! isset($this->marker[$point1]))
        {
            return '';
        }

        if ( ! isset($this->marker[$point2]))
        {
            $this->marker[$point2] = microtime();
        }

        //这里为什么要用到list，是因为microtime();返回值是“msec sec”的格式。
        list($sm, $ss) = explode(' ', $this->marker[$point1]);
        list($em, $es) = explode(' ', $this->marker[$point2]);

        return number_format(($em + $es) - ($sm + $ss), $decimals);
    }

    // --------------------------------------------------------------------

    /**
     * Memory Usage
     */
    function memory_usage()
    {
        //Output::_display();
        return '{memory_usage}';
    }

}